package tests;

import static org.junit.Assert.*;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.Test;

import main.Paycheck;
import paydayTransaction.PaydayTransaction;
import serviceChargeTransaction.ServiceChargeTransaction;
import timeCardTransaction.TimeCardTransaction;
import changeEmployeeTransaction.changeAffiliationTransaction.ChangeMemberTransaction;
import database.InMemoryPayrollDatabase;
import database.PayrollDatabase;
import addEmployeeTransaction.AddHourlyEmployee;
import addEmployeeTransaction.AddSalariedEmployee;

public class TestUnionMember {
	PayrollDatabase database = InMemoryPayrollDatabase.getInstance();

	@Test
	public void SalariedUnionMemberDues() {
		int empId = 1;
		AddSalariedEmployee t = new AddSalariedEmployee(empId, "Bob", "Home", 1000.00, database);
		t.execute();
		int memberId = 7734;
		ChangeMemberTransaction cmt = new ChangeMemberTransaction(empId, memberId, 9.42, database);
		cmt.execute();
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date payDate = null;
		
		try {
			payDate = format.parse("2001-11-30");
		} catch (ParseException e) {
			fail("parse exception");
		}

		PaydayTransaction pt = new PaydayTransaction(payDate, database);
		
		pt.execute();
		
		
		
		Paycheck pc = pt.getPaycheck(empId);
		assertNotNull(pc);
		assertEquals(payDate, pc.getPayDate());
		assertEquals(1000.0, pc.getGrossPay(), .001);
		assertEquals("Hold", pc.getField("Disposition"));
	}

	@Test
	public void HourlyUnionMemberServiceCharge() {
		int empId = 1;
		AddHourlyEmployee t = new AddHourlyEmployee(empId, "Bill", "Home",
				15.24, database);
		t.execute();
		int memberId = 7734;
		ChangeMemberTransaction cmt = new ChangeMemberTransaction(empId,
				memberId, 9.42, database);
		cmt.execute();
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date payDate = null;
		
		try {
			payDate = format.parse("2001-11-30");
		} catch (ParseException e) {
			fail("parse exception");
		}
		ServiceChargeTransaction sct = new ServiceChargeTransaction(memberId,
				payDate, 19.42, database);
		TimeCardTransaction tct = new TimeCardTransaction(payDate, 8.0, empId,
				database);
		try {
			sct.execute();
			tct.execute();
		} catch (Exception e) {
			fail("exception");
		}
	
		PaydayTransaction pt = new PaydayTransaction(payDate, database);
		pt.execute();
		Paycheck pc = pt.getPaycheck(empId);
		assertNotNull(pc);
		assertEquals(payDate, pc.getPayPeriodEndDate());
		assertEquals(8 * 15.24, pc.getGrossPay(), .001);
		assertEquals("Hold", pc.getField("Disposition"));
		assertEquals(9.42 + 19.42, pc.getDeductions(), .001);
		assertEquals((8 * 15.24) - (9.42 + 19.42), pc.getNetPay(), .001);
	}

	@Test
	public void ServiceChargesSpanningMultiplePayPeriods() {
		int empId = 1;
		AddHourlyEmployee t = new AddHourlyEmployee(empId, "Bill", "Home",
				15.24, database);
		t.execute();
		int memberId = 7734;
		ChangeMemberTransaction cmt = new ChangeMemberTransaction(empId,
				memberId, 9.42, database);
		cmt.execute();
		
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date payDate = null;
		Date earlyDate = null;
		Date lateDate = null;
		
		try {
			payDate = format.parse("2001-11-09");
			earlyDate = format.parse("2001-11-02");
			lateDate = format.parse("2001-11-16");
		} catch (ParseException e) {
			fail("parse exception");
		}
		
		ServiceChargeTransaction sct = new ServiceChargeTransaction(memberId,
				payDate, 19.42, database);
	
		ServiceChargeTransaction sctEarly = new ServiceChargeTransaction(
				memberId, earlyDate, 100.00, database);
		
		ServiceChargeTransaction sctLate = new ServiceChargeTransaction(
				memberId, lateDate, 200.00, database);
		
		TimeCardTransaction tct = new TimeCardTransaction(payDate, 8.0, empId,
				database);
		try {
			sct.execute();
			sctEarly.execute();
			sctLate.execute();
			tct.execute();
		} catch(Exception e) {
			fail("U mad bro");
		}
		PaydayTransaction pt = new PaydayTransaction(payDate, database);
		pt.execute();
		Paycheck pc = pt.getPaycheck(empId);
		assertNotNull(pc);
		assertEquals(payDate, pc.getPayPeriodEndDate());
		assertEquals(8 * 15.24, pc.getGrossPay(), .001);
		assertEquals("Hold", pc.getField("Disposition"));
		assertEquals(9.42 + 19.42, pc.getDeductions(), .001);
		assertEquals((8 * 15.24) - (9.42 + 19.42), pc.getNetPay(), .001);
	}
}
